﻿#region Usings

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Xml.Linq;
using Fasterflect;
using Kazkommertsbank.Framework.Common;
using Kazkommertsbank.Framework.Model.Pay;
using Kazkommertsbank.Framework.Test.Components;
using log4net;

#endregion

namespace Kazkommertsbank.Framework.Test
{
    public partial class _Default : Page
    {
        private static readonly ILog logger = LogManager.GetLogger(typeof(_Default));
        private readonly KkbController _controller;
        private readonly IKkbOrder _order;
        private readonly KkbSettings _settings;

        public _Default()
        {
            _settings = KkbSettings.Init();
            _controller = new KkbController(_settings);
            _order = CreateOrder();
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if(!Page.IsPostBack)
            {
                if(!string.IsNullOrEmpty(UrlHelper.Param("result")))
                {
                    lblPaymentResult.Text = string.Format("Payment {0}!", UrlHelper.Param("result"));
                    btnPayNow.Visible = false;
                }                   
                else
                {
                    lblPaymentResult.Visible = false;
                    try
                    {
                        litSettings.Text = BuildSettingsView(_settings);
                        litOrder.Text = BuildOrderView(_controller.CreateOrderXml(_order.OrderID, _order.Amount), _order.Appendix.ToXmlString());
                    }
                    catch(Exception ex)
                    {
                        logger.Error("Page_Load", ex);
                    }
                }
            }
        }

        private IKkbOrder CreateOrder()
        {
            Random rnd = new Random();
            KkbOrder order = new KkbOrder();
            order.OrderID = rnd.Next(100000, 999999);
            order.Email = "kkb.test@gmail.com";

            Appendix appendix = new Appendix();

            for(int i = 0; i < 3; i++)
            {
                AppendixItem item = new AppendixItem();
                item.Name = RandomString(rnd.Next(5, 20));
                item.Number = i;
                item.Quantity = i + 1;
                item.Amount = rnd.Next(10, 1000) * item.Quantity;
                appendix.Items.Add(item);
            }

            order.Amount = appendix.Items.Sum(appendixItem => appendixItem.Amount);
            order.Appendix = appendix;

            return order;
        }

        private string BuildOrderView(string order, string appendix)
        {
            StringBuilder builder = new StringBuilder();
            builder.Append("<h1>Post Data</h1>");
            builder.Append("<h3>Order</h3>");
            builder.AppendFormat("<div><pre>{0}</pre></div>", HttpUtility.HtmlEncode(FormatXml(order)));
            builder.Append("<h3>Appendix</h3>");
            builder.AppendFormat("<div><pre>{0}</pre></div>", HttpUtility.HtmlEncode(FormatXml(appendix)));
            return builder.ToString();
        }

        private string BuildSettingsView(KkbSettings settings)
        {
            StringBuilder result = new StringBuilder();
            result.Append("<h1>Current Settings</h1>");

            foreach (PropertyInfo propertyInfo in settings.GetType().GetProperties())
                result.AppendFormat("<div><strong>{0}</strong>: {1}</div>",
                                    propertyInfo.Name,
                                    propertyInfo.IsStatic() ? propertyInfo.Get() : propertyInfo.Get(settings));

            return result.ToString();
        }

        private static string RandomString(int size)
        {
            const string CHARS = "abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ";
            char[] chars = new char[size];
            Random rnd = new Random();

            for(int i = 0; i < size; i++)
                chars[i] = CHARS[rnd.Next(0, CHARS.Length)];

            return new string(chars);
        }

        private static string FormatXml(string inputXml)
        {
            XElement element = XElement.Parse(inputXml);
            return element.ToString();
        }

        protected void btnPayNow_Click(object sender, EventArgs e)
        {
            try
            {
                _controller.StartPaymentTransaction(_order);
            }
            catch(Exception ex)
            {
                logger.Error("btnPayNow_Click", ex);
            }
        }
    }
}